package com.jinlia.show.modules.base.system.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jinlia.show.common.core.exception.MyRuntimeException;
import com.jinlia.show.modules.base.constant.MemberCardBalanceChangeEnum;
import com.jinlia.show.modules.base.system.entity.MemberCard;
import com.jinlia.show.modules.base.system.entity.MemberCardBalanceChange;
import com.jinlia.show.modules.base.system.entity.MemberCardBalancePool;
import com.jinlia.show.modules.base.system.mapper.MemberCardBalanceChangeMapper;
import com.jinlia.show.modules.base.wxapp.entity.MemberRechargeDiscount;
import com.jinlia.show.modules.base.wxapp.entity.PayOrder;
import com.jinlia.show.modules.base.wxapp.entity.User;
import com.jinlia.show.modules.base.wxapp.service.MemberRechargeDiscountMapperService;
import com.jinlia.show.modules.base.wxapp.service.PayOrderMapperService;
import com.jinlia.show.modules.base.wxapp.service.UserMapperService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
public class MemberCardBalanceChangeMapperService extends ServiceImpl<MemberCardBalanceChangeMapper, MemberCardBalanceChange> {
    @Autowired
    UserMapperService userMapperService;
    @Autowired
    MemberCardMapperService memberCardMapperService;
    @Autowired
    MemberRechargeDiscountMapperService memberRechargeDiscountMapperService;
    @Autowired
    PayOrderMapperService payOrderMapperService;
    @Autowired
    MemberCardBalancePoolMapperService memberCardBalancePoolMapperService;

    public List<MemberCardBalanceChange> getBalanceChange(Long userId) {
        User byId = userMapperService.getById(userId);
        if (byId.getMemberCardId() == null) {
            return Arrays.asList();
        }
        List<MemberCardBalanceChange> list = this.lambdaQuery()
                .eq(MemberCardBalanceChange::getMemberCardId, byId.getMemberCardId())
                .orderByDesc(MemberCardBalanceChange::getCreateTime)
                .list();
        return list;
    }


    /**
     * @param memberCard 付款的销售单
     * @return
     */
    @Transactional
    public MemberCardBalanceChange balancePayOrder(Long payOrderId,BigDecimal moneyChange, MemberCard memberCard) {
        BigDecimal subtract = memberCard.getBalance().subtract(moneyChange);
        if (memberCard.getBalance().compareTo(moneyChange) < 0) {
            throw new MyRuntimeException("余额不足!!!");
        } else {
            //更新会员余额

            memberCardMapperService.lambdaUpdate()
                    .set(MemberCard::getBalance,subtract)
                    .eq(MemberCard::getId, memberCard.getId())
                    .update();
        }
        MemberCardBalanceChange memberCardBalanceChange = new MemberCardBalanceChange();
        //余额变化记录
        memberCardBalanceChange.setMemberCardId(memberCard.getId());
        memberCardBalanceChange.setChangeEnum(MemberCardBalanceChangeEnum.XF.getValue());//变化类型消费
        memberCardBalanceChange.setChangeObjectId(payOrderId);//付款单id
        memberCardBalanceChange.setMoneyChange(moneyChange.negate());//变动金额
        memberCardBalanceChange.setAvailableBalance(subtract);//剩余余额
        memberCardBalanceChange.setRemark("余额支付订单");
        MemberCardBalancePool memberCardBalancePool = memberCardBalancePoolMapperService.updateAvailableBalance(moneyChange);
        memberCardBalanceChange.setAvailableBalancePool(memberCardBalancePool.getAvailableBalanceSum());
        this.save(memberCardBalanceChange);
        return memberCardBalanceChange;
    }

    /**
     * 通过付款单充值余额
     *
     * @param payOrder
     * @return
     */
    @Transactional
    public MemberCardBalanceChange balanceRechargeByPayOrder(PayOrder payOrder) {
        MemberCard oldMemberCard = memberCardMapperService.getById(payOrder.getPayForId());
        //更新会员余额
        BigDecimal newBalance = payOrder.getPaidAmount().add(Objects.isNull(oldMemberCard.getBalance()) ?
                BigDecimal.ZERO : oldMemberCard.getBalance());
        MemberCardBalanceChange memberCardBalanceChange = new MemberCardBalanceChange();
        //余额变化记录
        memberCardBalanceChange.setMemberCardId(oldMemberCard.getId());
        memberCardBalanceChange.setChangeEnum(MemberCardBalanceChangeEnum.CZ.getValue());//变化类型消费
        memberCardBalanceChange.setMoneyChange(payOrder.getPaidAmount());//变动金额
        memberCardBalanceChange.setAvailableBalance(newBalance);//变动后金额
        memberCardBalanceChange.setChangeObjectId(payOrder.getId());//支付id
        memberCardBalanceChange.setRemark("充值");
        MemberCardBalancePool memberCardBalancePool = null;
        if (Objects.nonNull(payOrder.getRechargeId())) {//充值活动
            MemberRechargeDiscount byIdMemberRechargeDiscount = memberRechargeDiscountMapperService.getById(payOrder.getRechargeId());
            //赠送的金额
            BigDecimal giftAmount = byIdMemberRechargeDiscount.getGetAmount().subtract(byIdMemberRechargeDiscount.getRechargeAmount());
            //余额变动记录合并
            memberCardBalanceChange.setAvailableBalance(newBalance.add(giftAmount));//充值活动，加上赠送金额
            memberCardBalanceChange.setMoneyChange(memberCardBalanceChange.getMoneyChange().add(giftAmount));//充值活动，加上赠送金额
            memberCardBalancePool = memberCardBalancePoolMapperService.updateRechargeSum(payOrder.getPaidAmount(), giftAmount);
            memberCardBalanceChange.setAvailableBalancePool(memberCardBalancePool.getAvailableBalanceSum());
        } else {
            memberCardBalancePool = memberCardBalancePoolMapperService.updateRechargeSum(payOrder.getPaidAmount(), BigDecimal.ZERO);
            memberCardBalanceChange.setAvailableBalancePool(memberCardBalancePool.getAvailableBalanceSum());
        }
        memberCardMapperService.lambdaUpdate()
                .eq(MemberCard::getId, oldMemberCard.getId())
                .set(MemberCard::getBalance, memberCardBalanceChange.getAvailableBalance())
                .update(new MemberCard());
        this.save(memberCardBalanceChange);
        return memberCardBalanceChange;
    }
}
